package com.sy.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.sy.config.RedisClient;
import com.sy.constant.AppConstant;
import com.sy.dto.*;
import com.sy.entity.*;

import com.sy.exception.NotFoundException;
import com.sy.exception.ShopSystemException;
import com.sy.mapper.*;
import com.sy.vo.CartProductParams;
import com.sy.vo.OrderItemParam;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.sql.Date;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Description:
 * @Param:
 * @return:
 * @Author: 朱天宇
 * @Date:
 */

@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private UserAddressMapper userAddressMapper;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderProductRefMapper orderProductRefMapper;
    @Autowired
    private GoodMapper goodMapper;
    @Autowired
    private FlavorMapper flavorMapper;
    @Autowired
    private PackagingMapper packagingMapper;
    @Autowired
    private UserService userService;
    @Autowired
    private PayMapper payMapper;

    @Autowired
    private RedisClient redisClient;

    @Autowired
    private GoodService goodService;


    @Override
    public Result getOrderItmes(Integer oid, String token) {
        List<OrderItem> orderItems = new ArrayList<>();
        Result result = new Result();
        try {
            if (null == oid || null == token) {
                throw new Exception("没有详细的订单信息参数，请重新进入");
            }
            User user = userService.LoginUser(token);
            UserAddress userDefalutAddress = userAddressMapper.getUserDefalutAddress(user.getId());
            List<Address> allAddressesByUserId = userService.getAllAddressesByUserId(token);
            List<OrderProductRef> orderProductRefs = orderProductRefMapper.getOrderProductRefs(oid);
            if (CollectionUtils.isEmpty(orderProductRefs)) {
                throw new NotFoundException("抱歉服务端错误");
            }
            BigDecimal totalpice = new BigDecimal("0.0");
            List<BigDecimal> smallprices = new ArrayList<>();
            for (OrderProductRef orderProductRef : orderProductRefs) {
                OrderItem orderItem = new OrderItem();
                Product product = goodMapper.getProductById(orderProductRef.getPid());
                orderItem.setProduct(product);
                orderItem.setCount(orderProductRef.getCount());
                orderItem.setFlavor(flavorMapper.getFlavorName(orderProductRef.getFid()));
                orderItem.setPackaging(packagingMapper.getPackagname(orderProductRef.getPackid()));
                Integer count = orderProductRef.getCount();
                orderItem.setCount(count);
                BigDecimal originalprice = product.getOriginalprice();
                BigDecimal multiply = originalprice.multiply(new BigDecimal(String.valueOf(count)));
                orderItem.setSmallPrice(multiply);
                smallprices.add(multiply);
                orderItems.add(orderItem);
            }

            for (BigDecimal bigDecimal : smallprices) {
                totalpice = totalpice.add(bigDecimal);
            }
            List<Pay> payMethods = payMapper.getPayMethods();
            List<Object> list = new ArrayList<>();
            list.add(orderItems);
            list.add(totalpice);
            list.add(allAddressesByUserId);
            list.add(userDefalutAddress);
            list.add(payMethods);
            result.setData(list);
            result.setCode(200);
        } catch (Exception e) {
            e.printStackTrace();
            result.setError(e.getMessage());
            result.setCode(500);
        }
        return result;
    }


    @Override
    public Order getOrderByid(Integer oid) {
        return orderMapper.selectById(oid);
    }

    /**
     * @Description: 获取所有的订单信息
     * @Author: 陈聪敏
     * @Date: 2020/3/15 0015 22:01
     */
    @Override
    public Result getOrders() {
        Result result = new Result();
        try {
            List<Order> orders = orderMapper.selectList(null);
            result.setData(orders);
            result.setCode(200);
        } catch (Exception e) {
            e.printStackTrace();
            result.setError(e.getMessage());
            result.setCode(500);
        }
        return result;
    }


   /**
     * @Description: 通过订单编号和时间获取所有订单信息
     * @Author: 陈聪敏
     * @Date: 2020/3/15 0015 22:04
     */
    @Override
    public Result getOrdersByCondition(String keyword, String times) {
        Result result = new Result();
        try {
            QueryWrapper<Order> wrapper = new QueryWrapper<>();
            if(!StringUtils.isBlank(keyword)){
                wrapper.eq("orderno",keyword);
            }
            if(!StringUtils.isBlank(times)){
                wrapper.eq("ordertime",times);
            }
            List<Order> orders = orderMapper.selectList(wrapper);
            result.setCode(200);
            result.setData(orders);
        } catch (Exception e) {
            e.printStackTrace();
            result.setError(e.getMessage());
            result.setCode(500);
        }
        return result;
    }

    /**
     * @Description: 通过产品名称和时间获取所有订单信息
     * @Author: 陈聪敏
     * @Date: 2020/3/15 0015 22:04
     */
    @Override
    public Result getOrdersByConditions(String keyword, String times) {
        Result result = new Result();
        try {
            QueryWrapper<Order> wrapper = new QueryWrapper<>();
            if(!StringUtils.isBlank(keyword)){
                wrapper.like("productname",keyword);
            }
            if(!StringUtils.isBlank(times)){
                wrapper.eq("ordertime",times);
            }
            List<Order> orders = orderMapper.selectList(wrapper);
            result.setCode(200);
            result.setData(orders);
        } catch (Exception e) {
            e.printStackTrace();
            result.setError(e.getMessage());
            result.setCode(500);
        }
        return result;
    }

    /**
     * @Description: 管理员发货操作
     * @Author: 陈聪敏
     * @Date: 2020/3/15 0015 22:07
     */
    @Override
    public Result deliverGoods(Integer id) {
        Result result = new Result();
        try {
            Order order = new Order();
            order.setId(id);
            order.setStatus("6");
            orderMapper.updateById(order);
            result.setCode(200);
        } catch (Exception e) {
            e.printStackTrace();
            result.setError(e.getMessage());
            result.setCode(500);
        }
        return result;
    }

    /**
     * @Description: 管理员退款操作
     * @Author: 陈聪敏
     * @Date: 2020/3/15 0015 22:07
     */
    @Override
    @Transactional
    public Result refund(Integer id) {
        Result result = new Result();
        try {
            Order order = orderMapper.selectById(id);
            Integer uid = order.getUid();
            BigDecimal money = order.getTotalprice();
            userService.refund(uid,money);
            order.setRefundstatus(1);
            orderMapper.updateById(order);
            result.setCode(200);
        } catch (Exception e) {
            e.printStackTrace();
            result.setError(e.getMessage());
            result.setCode(500);
        }
        return result;
    }

    /**
     * @Description: 删除订单信息
     * @Author: 陈聪敏
     * @Date: 2020/3/15 0015 22:07
     */
    @Override
    public Result delOrder(String id) {
        Result result = new Result();
        try {
            System.out.println(id);
            String[] idsInfo = id.split(",");
            List<Integer> idList = new ArrayList<>();
            for (int i = 0; i < idsInfo.length; i++) {
                idList.add(Integer.parseInt(idsInfo[i]));
            }
            orderMapper.deleteBatchIds(idList);
            result.setCode(200);
        } catch (Exception e) {
            e.printStackTrace();
            result.setError(e.getMessage());
            result.setCode(500);
        }
        return result;
    }

    /**
     * 商品详情生成订单
     * @Author: 孙玮立
     * @param token
     * @param orderItemParams
     * @return
     */
    @Override
    public Result generateOrder(String token, List<OrderItemParam> orderItemParams) {
        Result result = new Result();
        try {
            User user = userService.LoginUser(token);
            String redisTimerKey = AppConstant.SUBMIT_ORDER_TIMER_PREFIX + user.getId();
            String redisTimer = redisClient.get(redisTimerKey);
            if (StringUtils.isNotBlank(redisTimer)) {
                throw new ShopSystemException("订单提交过于频繁，请稍后再试");
            } else {
                redisClient.set(redisTimerKey, user.getId());
                redisClient.expire(redisTimerKey, AppConstant.SUBMIT_ORDER_TIME_INTERVAL);
            }
            BigDecimal multiply = new BigDecimal(0);
            Order order = new Order();
            order.setOrdertime(new Date(System.currentTimeMillis()));
            order.setStatus("2");
            order.setUid(user.getId());
            Set<String>  set=new HashSet<>();
            StringBuilder stringBuilder=new StringBuilder();
            for (OrderItemParam orderItemParam:orderItemParams){
                Integer count = orderItemParam.getCount();
                Integer pid = orderItemParam.getPid();
                Product product = goodService.getProductsByiId(pid);
                String productname = product.getProductname();
                if(set.add(productname)){//说明加成功了
                    stringBuilder.append(productname).append(",");
                }
                multiply.add(product.getPresentprice().multiply(new BigDecimal(count)));
            }
            String oidNo = redisClient.generateOrderId();
            String s = stringBuilder.toString();
            order.setProductname(s.substring(0,s.length()-1));
            order.setOrderno(oidNo);
            order.setQuantity(orderItemParams.size());
            order.setTotalprice(multiply);
            orderMapper.insert(order);
            QueryWrapper<Order> orderQueryWrapper = new QueryWrapper<>();
            orderQueryWrapper.eq("orderNo", oidNo);
            Integer orderId = orderMapper.selectOne(orderQueryWrapper).getId();
            for (OrderItemParam orderItemParam : orderItemParams) {
                String flavor = orderItemParam.getFlavor();
                String packaging = orderItemParam.getPackaging();
                Integer pid = orderItemParam.getPid();
                Integer count = orderItemParam.getCount();
                OrderProductRef orderProductRef = new OrderProductRef();
                orderProductRef.setCount(count);
                orderProductRef.setFid(Integer.parseInt(flavor));
                orderProductRef.setPackid(Integer.parseInt(packaging));
                orderProductRef.setPid(pid);
                orderProductRef.setOid(orderId);
                orderProductRefMapper.insert(orderProductRef);
            }
            result.setData(orderId);
            result.setCode(200);
        } catch (Exception e) {
            e.printStackTrace();
            result.setError(e.getMessage());
            result.setCode(500);
        }
        return result;
    }

    /**
     * 购物车生成订单
     *
     * @param token
     * @param cartProductParams
     * @return
     * @Author: 孙玮立
     */
    @Override
    public Result generateCartOrder(String token, List<CartProductParams> cartProductParams) {
        Result result = new Result();
        try {
            User user = userService.LoginUser(token);
            String redisTimerKey = AppConstant.SUBMIT_ORDER_TIMER_PREFIX + user.getId();
            String redisTimer = redisClient.get(redisTimerKey);
            if (StringUtils.isNotBlank(redisTimer)) {
                throw new ShopSystemException("订单提交过于频繁，请稍后再试");
            } else {
                redisClient.set(redisTimerKey, user.getId());
                redisClient.expire(redisTimerKey, AppConstant.SUBMIT_ORDER_TIME_INTERVAL);
            }
            BigDecimal multiply = new BigDecimal(0);
            Order order = new Order();
            order.setOrdertime(new Date(System.currentTimeMillis()));
            order.setStatus("2");
            order.setUid(user.getId());
            for (CartProductParams cartProductParam : cartProductParams) {
                Integer count = cartProductParam.getCount();
                Integer pid = cartProductParam.getPid();
                Product product = goodService.getProductsByiId(pid);
                multiply.add(product.getPresentprice().multiply(new BigDecimal(count)));
            }
            System.out.println(multiply);
            String oidNo = redisClient.generateOrderId();
            order.setOrderno(oidNo);
            order.setQuantity(cartProductParams.size());
            order.setTotalprice(multiply);
            orderMapper.insert(order);
            QueryWrapper<Order> orderQueryWrapper = new QueryWrapper<>();
            orderQueryWrapper.eq("orderNo", oidNo);
            Integer orderId = orderMapper.selectOne(orderQueryWrapper).getId();

            for (CartProductParams cartProductParam : cartProductParams) {
                Integer pid = cartProductParam.getPid();
                String redisCartKey = AppConstant.USER_CART_REDIS_PREFIX + user.getId();
                String hget = redisClient.hget(redisCartKey, String.valueOf(pid));
                List<String> list = Arrays.asList(hget.split(","));
                String flavor = list.get(0);
                String packaging = list.get(1);
                String count = list.get(2);
                OrderProductRef orderProductRef = new OrderProductRef();
                orderProductRef.setCount(Integer.parseInt(count));
                QueryWrapper<Flavor> flavorQueryWrapper = new QueryWrapper<>();
                flavorQueryWrapper.eq("pid", pid).eq("flavor", flavor);
                Flavor flavorInfo = flavorMapper.selectOne(flavorQueryWrapper);
                orderProductRef.setFid(flavorInfo.getId());
                QueryWrapper<Packaging> packagingQueryWrapper = new QueryWrapper<>();
                packagingQueryWrapper.eq("pid", pid).eq("packaging", packaging);
                Packaging packagingInfo = packagingMapper.selectOne(packagingQueryWrapper);
                orderProductRef.setPackid(packagingInfo.getId());
                orderProductRef.setPid(pid);
                orderProductRef.setOid(orderId);
                orderProductRefMapper.insert(orderProductRef);
            }
            result.setData(orderId);
            result.setCode(200);
        } catch (Exception e) {
            e.printStackTrace();
            result.setError(e.getMessage());
            result.setCode(500);
        }
        return result;
    }

    @Override
    public Result getIntegrationHistory(Integer id) {
        Result result = new Result();
        try {
            User user = userService.getUser(String.valueOf(id));
            QueryWrapper<Order> orderQueryWrapper = new QueryWrapper<>();
            orderQueryWrapper.eq("uid",user.getId()).eq("evaluatestatus",1);
            List<Order> orders = orderMapper.selectList(orderQueryWrapper);
            List<IntegrationInfos> integrationInfos = new ArrayList<>();
            for (Order order:orders){
                IntegrationInfos integrationInfo = new IntegrationInfos();
                Date ordertime = order.getOrdertime();
                integrationInfo.setTime(ordertime);
                integrationInfo.setUserName(user.getUserName());
                Integer id1 = order.getId();
                QueryWrapper<OrderProductRef> orderProductRefQueryWrapper = new QueryWrapper<>();
                orderProductRefQueryWrapper.eq("oid",id1);
                List<OrderProductRef> orderProductRefs = orderProductRefMapper.selectList(orderProductRefQueryWrapper);
                for (OrderProductRef orderProductRef : orderProductRefs){
                    Integer pid = orderProductRef.getPid();
                    Product product = goodService.getProductsByiId(pid);
                    integrationInfo.setIntegral(product.getPresentprice().intValue());
                    integrationInfo.setPrice(product.getPresentprice());
                    integrationInfo.setProductName(product.getProductname());
                    integrationInfos.add(integrationInfo);
                }
            }
            result.setData(integrationInfos);
            result.setCode(200);
        } catch (Exception e) {
            e.printStackTrace();
            result.setError(e.getMessage());
            result.setCode(500);
        }
        return result;
    }

    @Override
    public Result getBrowseHistory(Integer id) {
        Result result = new Result();
        try {
            User user = userService.getUser(String.valueOf(id));
            QueryWrapper<History> historyQueryWrapper = new QueryWrapper<>();
            historyQueryWrapper.eq("uid",user.getId());
            List<History> histories = historyMapper.selectList(historyQueryWrapper);
            List<Browses> browsesList = new ArrayList<>();
            for (History history :histories){
                Browses browses = new Browses();
                Integer pid = history.getPid();
                Product product = goodService.getProductsByiId(pid);
                Timestamp browsestime = history.getBrowsestime();
                browses.setPrice(product.getPresentprice());
                browses.setProductName(product.getProductname());
                browses.setTime(browsestime);
                browses.setUserName(user.getUserName());
                browses.setViewNum(product.getVolume());
                browsesList.add(browses);
            }
            result.setData(browsesList);
            result.setCode(200);
        } catch (Exception e) {
            e.printStackTrace();
            result.setError(e.getMessage());
            result.setCode(500);
        }
        return result;
    }

    @Override
    public Result getOrderHistory(Integer id) {
        Result result = new Result();
        try {
            User user = userService.getUser(String.valueOf(id));
            QueryWrapper<Order> orderQueryWrapper = new QueryWrapper<>();
            orderQueryWrapper.eq("uid",user.getId());
            List<Order> orders = orderMapper.selectList(orderQueryWrapper);
            List<OrderInfo> orderInfos = new ArrayList<>();
            for (Order order:orders){
                OrderInfo orderInfo = new OrderInfo();
                orderInfo.setOrderNo(order.getOrderno());
                orderInfo.setCount(order.getQuantity());
                //1是已付款，2是未付款 3已退款，4待退款 5已发货，6未发货 7已收货，8未收货 9已评价，10未评价
                String status = order.getStatus();
                if (StringUtils.equals(status,"1")){
                    orderInfo.setStatus("已付款");
                }
                if (StringUtils.equals(status,"2")){
                    orderInfo.setStatus("未付款");
                }
                if (StringUtils.equals(status,"3")){
                    orderInfo.setStatus("已退款");
                }
                if (StringUtils.equals(status,"4")){
                    orderInfo.setStatus("待退款");
                }
                if (StringUtils.equals(status,"5")){
                    orderInfo.setStatus("已发货");
                }
                if (StringUtils.equals(status,"6")){
                    orderInfo.setStatus("未发货");
                }
                if (StringUtils.equals(status,"7")){
                    orderInfo.setStatus("已收货");
                }
                if (StringUtils.equals(status,"8")){
                    orderInfo.setStatus("未收货");
                }
                if (StringUtils.equals(status,"9")){
                    orderInfo.setStatus("已评价");
                }
                if (StringUtils.equals(status,"10")){
                    orderInfo.setStatus("未评价");
                }

                orderInfo.setTime(order.getOrdertime());
                orderInfo.setUserName(user.getUserName());
                orderInfos.add(orderInfo);
            }
            result.setData(orderInfos);
            result.setCode(200);
        } catch (Exception e) {
            e.printStackTrace();
            result.setError(e.getMessage());
            result.setCode(500);
        }
        return result;
    }
}
